package com.gusto.engine.semsim.measures.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.gusto.engine.beans.exceptions.PropertyAccessException;
import com.gusto.engine.beans.model.Res;
import com.gusto.engine.semsim.exceptions.SimilarityException;
import com.gusto.engine.semsim.measures.CompoundValueSimilarity;
import com.gusto.engine.semsim.measures.ResourceSimilarity;

/**
 * <p>The {@link CompoundSimilarity} measure allows to apply several property values
 * on a single similarity measure.
 * </p>
 * 
 * @author amokrane.belloui@gmail.com
 */
public class CompoundSimilarity implements ResourceSimilarity {
	
	private Logger log = Logger.getLogger(CompoundSimilarity.class);
	
	private CompoundValueSimilarity similarity;
	public void setSimilarity(CompoundValueSimilarity similarity) {
		this.similarity = similarity;
	}
	
	private List<CompoundSimilarityParam> properties = new ArrayList<CompoundSimilarityParam>();
	public void setProperties(List<CompoundSimilarityParam> properties) {
		this.properties = properties;
	}
	public List<CompoundSimilarityParam> getProperties() {
		return properties;
	}
	
	public CompoundSimilarity() {
		
	}
	
	public Double getSimilarity(Res res1, Res res2) throws SimilarityException, PropertyAccessException {
		log.debug("Calculating composed similarity");
		
		Map<String, Object> values1 = new HashMap<String, Object>();
		Map<String, Object> values2 = new HashMap<String, Object>();
		
		for (CompoundSimilarityParam param : properties) {
			
			log.debug("Using property '" + param.getProperty() + "' for param: " + param.getName());
			
			values1.put(param.getName(), res1.getValueProperty(param.getProperty()));
			values2.put(param.getName(), res2.getValueProperty(param.getProperty()));
			log.debug("Component " + similarity.getClass().getSimpleName());
		}
		
		Double sim = similarity.getSimilarity(values1, values2);
		
		log.info("Compound similarity (" + res1  + ", " + res2 + ") for properties XXX = " + (sim));
		return (sim);
	}
	
	public String getId() {
		String id = "<"  + getClass().getName() + "|";
		id += similarity.getId() + "|";
		for (CompoundSimilarityParam prop : properties) {
			id += prop.getName() + "|";
			id += prop.getProperty() + "|";
		}
		id += ">";
		return id;
	}
	
}
